package cn.jarlen.jwt.tools.crypt.device.soft;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;

import cn.jarlen.jwt.tools.crypt.base.CryptoAppKitProperties;
import cn.jarlen.jwt.tools.crypt.base.KeyCache;
import cn.jarlen.jwt.tools.crypt.base.P12Info;

public class P12CertOperator {
    private static final String KEY_STONE_TYPE = "PKCS12";
    private static final int CERT_VALIDITY_TYPE_OCSP = 2;
    KeyCache keyCache = KeyCache.getInstance();
    CryptoAppKitProperties.Soft soft = CryptoAppKitProperties.getInstance().getSoft();
    private static final P12CertOperator p12CertOperator = new P12CertOperator();

    public P12CertOperator() {
    }

    public static P12CertOperator getInstance() {
        return p12CertOperator;
    }

    public void initCert() throws UnrecoverableKeyException, CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException {
        P12Info signCertInfo = this.getCertInfo(this.soft.getSignKeyStoreFile(), this.soft.getSignKeyPasswd());
        P12Info encCertInfo = this.getCertInfo(this.soft.getEncKeyStoreFile(), this.soft.getEncKeyPasswd());
        this.keyCache.setSignP12Info(signCertInfo);
        this.keyCache.setEncP12Info(encCertInfo);
    }

    private P12Info getCertInfo(String filePath, String psd) throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
        FileInputStream fin = new FileInputStream(filePath);
        KeyStore ks = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());
        ks.load(fin, psd.toCharArray());
        PrivateKey priKey = (PrivateKey)ks.getKey((String)ks.aliases().nextElement(), psd.toCharArray());
        Certificate cert = ks.getCertificate((String)ks.aliases().nextElement());
        PublicKey pubKey = cert.getPublicKey();
        P12Info p12Info = new P12Info();
        p12Info.setCert(cert);
        p12Info.setPubKey(pubKey);
        p12Info.setPriKey(priKey);
        return p12Info;
    }
}
